import datetime
import os
import time
import requests
import jwt
from Cryptodome.Util.py3compat import tostr
from qiniu import Auth
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response

from tools import myjwt
from tools.SFlogin import f
from user import models, seruser
import random
from tools.myredis import r
from tools.myjwt import mytoken
from tools.BaiDusfsb import BaiduOCRTool
from xm3 import settings


class SendcodeView(APIView):
    def post(self, request):
        phone = request.data.get('phone')
        # 发送验证码
        code = random.randint(1000, 9999)
        # dcode = tredis.get_str_time(phone)
        # if dcode:
        #     return Response({'message': '验证码已发送,请2分钟后再试'})
        r.setex_str(phone, 120, code)
        return Response({'message': '验证码发送成功', 'code': 200, 'sms': code})


class LoginView(APIView):
    def post(self, request):
        phone = request.data.get('phone')
        code = request.data.get('code')
        ecode = r.get_str(phone)
        print(ecode)
        if str(code) == str(ecode):
            user = models.Users.objects.filter(phone=phone).first()
            if user:
                userid = user.id
                username = user.name
                user = {'userid': userid, 'username': username, 'exp': int(time.time()) + 60 * 60}
                user1 = {'userid': userid, 'username': username, 'exp': int(time.time()) + 60 * 60 * 2}
                token = mytoken.settoken(user)
                retoken = mytoken.settoken(user1)
                return Response(
                    {'message': '登录成功', 'token': token, 'retoken': retoken, 'code': 200, 'userid': userid})
            else:
                user = models.Users.objects.create(phone=phone, name=phone)
                userid = user.id
                username = user.name

                user = {'userid': userid, 'username': username, 'exp': int(time.time()) + 60 * 60}
                user1 = {'userid': userid, 'username': username, 'exp': int(time.time()) + 60 * 60 * 2}
                token = mytoken.settoken(user)
                retoken = mytoken.settoken(user1)
                return Response(
                    {'message': '登录成功', 'token': token, 'retoken': retoken, 'code': 200, 'userid': userid})
        else:
            return Response({'message': '验证码错误或已过期'})


class ReTokenView(APIView):
    def post(self, request):
        retoken = request.data.get('token')
        data = mytoken.gettoken(retoken)
        userid = data.get('userid')
        username = data.get('username')
        user = {'userid': userid, 'username': username, 'exp': int(time.time()) + 60 * 60}
        user1 = {'userid': userid, 'username': username, 'exp': int(time.time()) + 60 * 60 * 2}
        token = mytoken.settoken(user)
        retoken = mytoken.settoken(user1)
        return Response({'message': '刷新成功', 'token': token, 'retoken': retoken})


class ExitLoginView(APIView):
    def post(self, request):
        # 获取请求数据
        token = request.data.get('token')
        userid = request.data.get('userid')

        if not token or not userid:
            return Response({'message': 'token 和 userid 不能为空'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            # 解析 JWT
            data = mytoken.gettoken(token)
            userid1 = data.get('userid')
            exp = data.get('exp')

            # 验证 userid
            if userid != userid1:
                return Response({'message': 'userid 不匹配'}, status=status.HTTP_400_BAD_REQUEST)

            # 检查 token 是否已过期
            current_time = time.time()
            if exp < current_time:
                return Response({'message': 'token 已过期'}, status=status.HTTP_400_BAD_REQUEST)

            # 计算剩余时间
            remaining_time = exp - current_time
            if remaining_time < 0:
                remaining_time = 0

            # 将 token 存入 Redis
            r.setex_str(userid, int(remaining_time), token)

            return Response({'message': '退出成功'}, status=status.HTTP_200_OK)

        except jwt.ExpiredSignatureError:
            return Response({'message': 'token 已过期'}, status=status.HTTP_400_BAD_REQUEST)
        except jwt.InvalidTokenError:
            return Response({'message': '无效的 token'}, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            # 捕获其他异常（如 Redis 操作失败）
            return Response({'message': f'服务器错误: {str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class DingLoginView(APIView):
    """
    第三方登录
    """

    def post(self, request):
        """
        用户登录
        :param request:
        :return:
        """
        types = request.data.get("types")
        print(types)
        r.set_str("types", types)
        factory = f.create_login(types)
        url = factory.get_url()
        return Response({"code": 200, "msg": "登录成功", "url": url})


class LoginCallbackView(APIView):
    """
    用户登录回调
    """

    def get(self, request):
        """
        用户登录回调
        :param request:
        :return:
        """
        types = request.query_params.get('types')  # 设置默认登录类型
        if not types:
            return Response({"code": 400, "msg": "登录类型不能为空"}, status=status.HTTP_400_BAD_REQUEST)
        r.setex_str("types", 120, types)
        print(types)
        factory = f.create_login(types)
        query = factory.roll_bcak(request)
        return Response(
            {"code": 200, "msg": "回调成功", "data": query})


class QnToken(APIView):
    def get(self, request):
        # 需要填写你的 Access Key 和 Secret Key
        access_key = 'ND6f-9XPO4qoEn19Ul38pYjq6m2C6Lsyr-wW_D6V'
        secret_key = '53memSmvwSQesPygbN3dHDwx2_bhfaJmrQzmI6EJ'
        # 构建鉴权对象
        q = Auth(access_key, secret_key)
        # 要上传的空间
        bucket_name = '2409a-1'

        # 3600为token过期时间，秒为单位。3600等于一小时
        token = q.upload_token(bucket_name)
        return Response({"code": 10000, 'data': token})


class OCRView(APIView):
    def post(self, request, *args, **kwargs):
        # 从请求中获取API密钥和图像URL（在实际应用中，你应该使用更安全的方式来传递这些敏感信息）
        ak = "9zEW0fGeNpW1kdolG0obOkp2"
        # 文字识别应用的API Key
        sk = "mjZjeGxGqrfeHrnPyGU9wgZqtLKTK6Qt"
        image_url = request.data.get('image_url')
        print(image_url)
        p = image_url.split('/')[-1]
        url = 'http://ssdfrh98q.hb-bkt.clouddn.com/' + p

        if not image_url:
            return Response({'error': 'Missing required parameters'}, status=status.HTTP_400_BAD_REQUEST)

        # 初始化OCR工具
        baidu_ocr = BaiduOCRTool(ak, sk)

        try:
            # 发送OCR请求（注意：这里的send_ocr_request方法可能需要调整以适应实际的OCR库API）
            ocr_result = baidu_ocr.send_ocr_request(url)
            if ocr_result:
                pass
            return Response({'code':200,'data':ocr_result}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class UPphone(APIView):
    def post(self, request):
        phone = request.data.get('phone')
        newphone = request.data.get('newphone')
        code = request.data.get('code')
        if not phone or not newphone or not code:
            return Response({'error': 'Missing required parameters'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            user = models.Users.objects.get(phone=phone)
            if user:
                rcode = r.get_str(newphone)
                if str(rcode) == str(code):
                    user.phone = newphone
                    user.save()
                    return Response({'message': '手机号修改成功'}, status=status.HTTP_200_OK)
                else:
                    return Response({'message': '验证码错误'}, status=status.HTTP_400_BAD_REQUEST)
            else:
                return Response({'message': '手机号不存在'}, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class UserView(APIView):
    def get(self, request):
        userid = request.query_params.get('userid')
        if not userid:
            return Response({'error': 'Missing required parameters'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            user = models.Users.objects.get(id=userid)
            if user:
                ser = seruser.UserSerializer(user)
                return Response(ser.data, status=status.HTTP_200_OK)
            else:
                return Response({'message': '用户不存在'}, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class AvatarUploadView(APIView):
    authentication_classes = [myjwt.JWTAuthentication]


    def post(self, request):
        auth_header = request.META.get('HTTP_AUTHORIZATION', '').split()
        print(auth_header)
        if len(auth_header) != 2 or auth_header[0].lower() != 'bearer':
            return Response({'code': 403, 'message': '未提供有效Token'}, status=status.HTTP_403_FORBIDDEN)
        
        try:
            token = auth_header[1]
            payload = mytoken.gettoken(token)
            userid = payload.get('userid')
            if not userid:
                raise jwt.InvalidTokenError
        except jwt.ExpiredSignatureError:
            return Response({'code': 403, 'message': 'Token已过期'}, status=status.HTTP_403_FORBIDDEN)
        except jwt.InvalidTokenError:
            return Response({'code': 403, 'message': '无效Token'}, status=status.HTTP_403_FORBIDDEN)
        chunk = request.FILES.get('chunk')
        filename = request.POST.get('filename')
        chunk_index = int(request.POST.get('chunkIndex'))
        total_chunks = int(request.POST.get('totalChunks'))
        
        # 创建用户临时目录
        temp_dir = os.path.join(settings.MEDIA_ROOT, 'temp', str(userid), filename)
        os.makedirs(temp_dir, exist_ok=True)
        
        # 保存分片文件
        chunk_path = os.path.join(temp_dir, f'{filename}.part{chunk_index}')
        with open(chunk_path, 'wb') as f:
            for chunk_data in chunk.chunks():
                f.write(chunk_data)
        
        return Response({'code': 200, 'message': '分片上传成功', 'received': chunk_index})

class AvatarMergeView(APIView):
    authentication_classes = [myjwt.JWTAuthentication]
    
    def post(self, request):
        auth_header = request.META.get('HTTP_AUTHORIZATION', '').split()
        if len(auth_header) != 2 or auth_header[0].lower() != 'bearer':
            return Response({'code': 403, 'message': '未提供有效Token'}, status=status.HTTP_403_FORBIDDEN)
        try:
            filename = request.POST.get('filename')
            total_chunks = int(request.POST.get('totalChunks'))
            token = auth_header[1]
            payload = mytoken.gettoken(token)
            userid = payload.get('userid')
            if not userid:
                raise jwt.InvalidTokenError
            temp_dir = os.path.join(settings.MEDIA_ROOT, 'temp', str(userid), filename)
            avatar_dir = os.path.join(settings.MEDIA_ROOT, 'avatars', str(userid))
            os.makedirs(avatar_dir, exist_ok=True)
            final_path = os.path.join(avatar_dir, filename)
            with open(final_path, 'wb') as final_file:
                for i in range(total_chunks):
                    chunk_path = os.path.join(temp_dir, f'{filename}.part{i}')
                    try:
                        with open(chunk_path, 'rb') as chunk_file:
                            final_file.write(chunk_file.read())
                        os.remove(chunk_path)
                    except FileNotFoundError:
                        return Response({'code': 400, 'message': '分片文件缺失'}, status=400)
            user_model = models.Users.objects.get(id=userid)
            user_model.img = os.path.join('avatars', str(user_model.id), filename)
            user_model.save()

            # 清理临时目录
            os.rmdir(temp_dir)

            return Response({'code': 200, 'message': '文件合并成功', 'avatar_url': str(user_model.img)})
        except jwt.ExpiredSignatureError:
            return Response({'code': 403, 'message': 'Token已过期'}, status=status.HTTP_403_FORBIDDEN)
        except jwt.InvalidTokenError:
            return Response({'code': 403, 'message': '无效Token'}, status=status.HTTP_403_FORBIDDEN)

            # 临时目录路径

            # 最终存储路径


            # 合并文件

        # 更新用户头像URL


class UpdateUsername(APIView):
    def post(self, request):
        new_name = request.data.get('name')
        if not 2 <= len(new_name) <= 20:
            return Response({'code':400, 'message':'用户名长度需在2-20字符之间'})
        
        user = request.user
        user.name = new_name
        user.save()
        
        return Response({
            'code':200,
            'message':'修改成功',
            'data':seruser.UserSerializer(user).data
        })
